package chaoyue.study.safe;

import chaoyue.study.ThreadUtils;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * condition可以理解为在在juc包下的wait和notify，配合lock进行使用
 * (Object中的wait和notify是配合synchronized使用)
 */
public class ConditionTest {
    private static int num = 10;
    private static int count = 0;
    private static final Lock lock = new ReentrantLock();
    private static final Condition condition = lock.newCondition();

    public static void main(String[] args) {
        // 消费者线程
        Thread consumerThread = new Thread(() -> {
            while (true) {
                ThreadUtils.sleep(1000);
                minus();
            }
        });

        // 生产者线程
        Thread producerThread = new Thread(() -> {
            while (true) {
                ThreadUtils.sleep(2000);
                plus();
            }
        });

        consumerThread.start();
        producerThread.start();
    }

    public static void minus() {
        lock.lock();
        if (num <= 0) {
            try {
                // 如果num不足，则当前线程基于MONITOR阻塞，等待生产者生产
                condition.await();
            } catch (InterruptedException ignored) {
            }
        }
        num--;
        System.out.println("消费者消费 剩余: " + num);
        lock.unlock();
    }

    public static void plus() {
        lock.lock();
        if (num >= 10) {
            // 如果num超过10个，唤醒wait在MONITOR对象上的线程执行（注意：当前线程并不会阻塞）
            condition.signal();
        }
        num++;
        count++;
        System.out.println("生产者生产 剩余: " + num + " 总共生产: " + count);
        lock.unlock();
    }
}
